import { computed, type Ref } from 'vue'

import { type MimoContent, ModulationMode } from '@/apis/lab'
import type { TableColumnData } from '@arco-design/web-vue'
import type { TableSlotCell } from '@/types/components-tool'
import type { RadioOption } from '@arco-design/web-vue/es/radio/interface'

export const enum DecodeStatus {
  NULL,
  Running,
  Matched,
  Unmatched
}

export const modulationModeName = {
  [ModulationMode.FourQAM]: '4QAM',
  [ModulationMode.FourASK]: '4ASK',
  [ModulationMode.FourFSK]: '4FSK'
} as const satisfies Record<ModulationMode, string>

export const modulationModeOptions = [
  {
    label: modulationModeName[ModulationMode.FourQAM],
    value: ModulationMode.FourQAM
  },
  {
    label: modulationModeName[ModulationMode.FourASK],
    value: ModulationMode.FourASK
  },
  {
    label: modulationModeName[ModulationMode.FourFSK],
    value: ModulationMode.FourFSK
  }
] as const satisfies RadioOption[]

export type CellSlotProps = TableSlotCell<{
  bitStream: string
  result: string
  status: DecodeStatus
  receiveAntennas: number
  modulationMode: ModulationMode
  noiseRate: number
  key: string
  editable: boolean
}>
export function useDecodeTable(
  decodeList: Ref<Required<MimoContent>['decode']>,
  editableKey: Ref<string>
) {
  const toBinary = (num: number): string => num.toString(2).padStart(4, '0')

  const resultFormatter = (result?: number): string => {
    return result === undefined ? '' : toBinary(result)
  }

  const statusFormatter = (bitStream: number, result?: number): DecodeStatus => {
    switch (result) {
      case undefined:
        return DecodeStatus.Running
      case -1:
        return DecodeStatus.NULL
      default:
        return result === bitStream ? DecodeStatus.Matched : DecodeStatus.Unmatched
    }
  }

  const data = computed<CellSlotProps['record'][]>(() => {
    return Object.entries(decodeList.value)
      .map(([key, { args, result }]) => ({
        key,
        ...args,
        editable: key === editableKey.value,
        bitStream: toBinary(args.bitStream),
        result: resultFormatter(result),
        status: statusFormatter(args.bitStream, result)
      }))
      .sort((a, b) => +a.key - +b.key)
  })

  return {
    data,
    columns: [
      {
        align: 'center',
        dataIndex: 'key',
        title: '编号',
        width: 60,
        fixed: 'left'
      },
      {
        align: 'center',
        title: '发射天线数',
        slotName: 'transmitAntennas',
        width: 110
      },
      {
        align: 'center',
        title: '接收天线数',
        slotName: 'receiveAntennas',
        width: 110
      },
      {
        align: 'center',
        title: '调制方式',
        slotName: 'modulationMode',
        width: 160
      },
      {
        align: 'center',
        title: '信噪比',
        slotName: 'noiseRate',
        width: 120
      },
      {
        align: 'center',
        title: '比特流',
        slotName: 'bitStream',
        width: 160
      },
      {
        align: 'center',
        slotName: 'result',
        title: '解调结果',
        width: 90
      },
      {
        align: 'center',
        slotName: 'edit',
        title: '参数修改',
        width: 90,
        fixed: 'right'
      }
    ] as const satisfies TableColumnData[]
  }
}
